package ejb.com.bbva.cbm.service.ejb;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

//import javax.ejb.TransactionAttribute;
//import javax.ejb.TransactionAttributeType;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import oracle.jdbc.driver.OracleTypes;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cbm.commons.Conexion;
import ejb.cbm.admin.entity.ParametroEntity;
import ejb.cbm.commons.JdbcHelper;
import ejb.cbm.operatoria.entity.ChequeEntity;
import ejb.cbm.operatoria.entity.ClienteEntity;
import ejb.cbm.operatoria.entity.OperacionChequeEntity;
import ejb.cbm.operatoria.entity.OperacionEfectivoEntity;
import ejb.com.bbva.cbm.dominio.Caja;
import ejb.com.bbva.cbm.dominio.CuentaEntityDTO;
import ejb.com.bbva.cbm.dominio.MontoDenominacion;
import ejb.com.bbva.cbm.dominio.TraspasoCajaEntity;
import ejb.com.bbva.cbm.dominio.TraspasoConfirmacionEntity;
import ejb.com.bbva.cbm.service.ComunServiceLocal;
import ejb.com.bbva.cbm.service.OperativaServiceLocal;
import ejb.com.bbva.cbm.util.Constante;
import ejb.com.bbva.cbm.util.DatosConsultaSaldoFinal;
import ejb.com.bbva.cbm.util.DatosConsultaSaldoFinal.SaldoDenominacion;
import ejb.com.bbva.cbm.util.DatosConsultaSaldoFinal.SaldoTotal;
import ejb.com.bbva.cbm.util.DatosConsultaSaldoFinal.Terminal;
import ejb.com.bbva.cbm.util.DatosTraspasoCaja;
import ejb.com.bbva.cbm.util.NegocioException;
import ejb.com.bbva.cbm.util.Opcion;
import ejb.com.bbva.cbm.util.DatosConsultaSaldoFinal.SaldoTerminal;

/**
 * Session Bean implementation class OperativaBean
 */
@Service("operativaServiceLocal")
public class OperativaServiceBean  extends HibernateDaoSupport implements OperativaServiceLocal {

    
    private ComunServiceLocal comunServiceLocal;
    
    @Autowired
    public void setComunServiceLocal(ComunServiceLocal comunServiceLocal) {
		this.comunServiceLocal = comunServiceLocal;
	}
    
    @Autowired
	public OperativaServiceBean(SessionFactory sessionFactory){
		super.setSessionFactory(sessionFactory);
	}
    
    /**
     * Default constructor. 
     */
    public OperativaServiceBean() {
        // TODO Auto-generated constructor stub
    	
    }
    
    private Connection getConnection()
    {
    	/*OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
    	return (Connection) kem.getConnection();*/
    	return Conexion.getConnection();
    }
    
    //@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<ClienteEntity> buscarCliente(String tipoDocumento,String numeroDocumento,
    										 String nombre,String primerApellido,String segundoApellido,String razonSocial) throws Exception {
    	StringBuilder query = new StringBuilder();
    	String sql = "select o from ClienteEntity o ";
    	
    	
    	if(tipoDocumento!=null){
    		query.append(" o.codigoidentificacion = :tipoDocumento and ");
    	}
    	
    	if(numeroDocumento!=null){
    		query.append(" o.numerocliente = :numeroDocumento and ");
    	}
    	
    	if(nombre!=null){
    		query.append(" upper(o.nombrecliente) like :nombre and ");
    	}
    	
    	if(primerApellido!=null){
    		query.append(" upper(o.primerapellido) like :primerApellido and ");
    	}
    	
    	if(segundoApellido!=null){
    		query.append(" upper(o.segundoapellido) like :segundoApellido and ");
    	}
    	
    	if(razonSocial!=null){
    		query.append(" upper(o.descripcionetiquetacomercial) like :razonSocial and ");
    	}
    	
    	query.append(" 1 = 1 ");
    	
    	if(query.length()>0){
    		sql+= " where "+query.toString();
    	}
    	
    	Query q = getSession().createQuery(sql);
    	
    	if(tipoDocumento!=null){
    		Integer tipo = Integer.parseInt(tipoDocumento);
    		q.setParameter("tipoDocumento", tipo);
    	}
    	
    	if(numeroDocumento!=null){
    		q.setParameter("numeroDocumento", numeroDocumento);
    	}
    	
    	if(nombre!=null){
    		nombre = "%"+nombre+"%";
    		q.setParameter("nombre", nombre);
    	}
    	
    	if(primerApellido!=null){
    		primerApellido = "%"+primerApellido+"%";
    		q.setParameter("primerApellido", primerApellido);
    	}
    	
    	if(segundoApellido!=null){
    		segundoApellido = "%"+segundoApellido+"%";
    		q.setParameter("segundoApellido", segundoApellido);
    	}
    	
    	if(razonSocial!=null){
    		segundoApellido = "%"+segundoApellido+"%";
    		q.setParameter("razonSocial", razonSocial);
    	}
    	
    	return q.list();
    }
    
    //@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<HashMap<String,String>> buscarCliente(String numeroCuenta,String numeroTarjeta,String tipoDocumento,String numeroDocumento,
    										 String nombre,String primerApellido,String segundoApellido,String razonSocial) throws Exception {
    	
    	CallableStatement cstmt=null;
    	String sCodError = null;
    	int ctaCuenta =0;
    	InitialContext ic = new InitialContext();
    	//DataSource ds = (DataSource) ic.lookup("jdbc/CONNEG"); 
    	Connection con = getConnection(); 
    	List<HashMap<String,String>> listaCuentas = new ArrayList<HashMap<String,String>>(); 
    	cstmt = con.prepareCall("{call conneg.PQ_CONTINUIDAD.sp_consultar_cliente_cuentas(?,?,?,?,?,?,?,?,?,?)}");      
        cstmt.setString(1,numeroCuenta);
        cstmt.setString(2,numeroTarjeta);
        cstmt.setString(3,tipoDocumento);
        cstmt.setString(4,numeroDocumento);
        cstmt.setString(5,nombre);
        cstmt.setString(6,primerApellido);
        cstmt.setString(7,segundoApellido);
        cstmt.setString(8,razonSocial);
        cstmt.registerOutParameter(9, OracleTypes.VARCHAR);
        cstmt.registerOutParameter(10, OracleTypes.CURSOR);
        cstmt.execute();
        
        sCodError = cstmt.getString(9);
        if(!sCodError.equals("SIN ERROR")){
            throw new SQLException(sCodError);
        }
        ResultSet rs = (ResultSet)cstmt.getObject(10);
        while(rs.next()) { 
            HashMap<String,String> mapCuenta = new HashMap<String,String>();
            mapCuenta.put("identificadorRegistro", String.valueOf(++ctaCuenta));
            mapCuenta.put("numerocuenta", rs.getString("NUMEROCUENTA"));
            mapCuenta.put("numerotarjeta", rs.getString("NUMEROTARJETA"));
            mapCuenta.put("divisa", rs.getString("divisa"));
            mapCuenta.put("CODIGODIVISA", rs.getString("CODIGODIVISA"));
            mapCuenta.put("producto", rs.getString("producto"));
            mapCuenta.put("subproducto", rs.getString("subproducto"));
            mapCuenta.put("nombrecliente", rs.getString("NOMBRECLIENTE"));
            mapCuenta.put("primerapellido", rs.getString("PRIMERAPELLIDO"));
            mapCuenta.put("segundoapellido", rs.getString("SEGUNDOAPELLIDO"));
            mapCuenta.put("razonsocial", rs.getString("razonsocial"));
            mapCuenta.put("codigoidentificacion", rs.getString("CODIGOIDENTIFICACION"));
            mapCuenta.put("tipodocumento", rs.getString("tipodocumento"));
            mapCuenta.put("numerodocumento", rs.getString("NUMEROIDENTIFICACION"));
            mapCuenta.put("saldodisponible", rs.getString("SALDODISPONIBLE"));
            mapCuenta.put("condicioncuenta", rs.getString("condicioncuenta"));
            mapCuenta.put("situacioncuenta", rs.getString("situacioncuenta"));
           
            listaCuentas.add(mapCuenta);
        }

    	return listaCuentas;
    }
    
    public List<HashMap<String,String>> buscarTarjeta(String numeroTarjeta,String tipoDocumento,String numeroDocumento,
			 String nombre,String primerApellido,String segundoApellido) throws Exception {
		CallableStatement cstmt = null;
		String sCodError = null;		
		Connection con = getConnection(); 
		List<HashMap<String,String>> listaCuentas = new ArrayList<HashMap<String,String>>(); 
		cstmt = con.prepareCall("{call conneg.PQ_CONTINUIDAD.sp_consultar_cliente_tarjetas(?,?,?,?,?,?,?,?)}");
		cstmt.setString(1,numeroTarjeta);
		cstmt.setString(2,tipoDocumento);
		cstmt.setString(3,numeroDocumento);
		cstmt.setString(4,nombre);
		cstmt.setString(5,primerApellido);
		cstmt.setString(6,segundoApellido);		
		cstmt.registerOutParameter(7, OracleTypes.VARCHAR);
		cstmt.registerOutParameter(8, OracleTypes.CURSOR);
		cstmt.execute();
		
		sCodError = cstmt.getString(7);
		if(!sCodError.equals("SIN ERROR")){
			throw new SQLException(sCodError);
		}
		
		ResultSet rs = (ResultSet)cstmt.getObject(8);
		while(rs.next()) { 
			HashMap<String,String> mapCuenta = new HashMap<String,String>();
			mapCuenta.put("identificadorTarjeta", rs.getString("CODIGOSECUENCIAL"));			
			mapCuenta.put("numerotarjeta", rs.getString("NUMEROTARJETA"));			
			mapCuenta.put("producto", rs.getString("producto"));
			mapCuenta.put("subproducto", rs.getString("subproducto"));
			mapCuenta.put("nombrecliente", rs.getString("NOMBRECLIENTE"));
			mapCuenta.put("primerapellido", rs.getString("PRIMERAPELLIDO"));
			mapCuenta.put("segundoapellido", rs.getString("SEGUNDOAPELLIDO"));
			mapCuenta.put("razonsocial", rs.getString("razonsocial"));
			//mapCuenta.put("codigoidentificacion", rs.getString("CODIGOIDENTIFICACION"));
			mapCuenta.put("tipodocumento", rs.getString("tipodocumento"));
			mapCuenta.put("numerodocumento", rs.getString("NUMEROIDENTIFICACION"));
			//Datos adicionales de la tarjeta.
			mapCuenta.put("tipotarjeta", rs.getString("TIPOTARJETA"));
			mapCuenta.put("descripciontarjeta", rs.getString("DESCRIPCIONTARJETA"));
			mapCuenta.put("entidadcontrato", rs.getString("ENTIDADCONTRATO"));
			mapCuenta.put("oficinacontrato", rs.getString("OFICINACONTRATO"));
			mapCuenta.put("tarjnumerodocumento", rs.getString("NUMERODOCUMENTO"));
			mapCuenta.put("indicadorsituacion", rs.getString("INDICADORSITUACION"));
			
			listaCuentas.add(mapCuenta);
		}
		
		JdbcHelper.close(con, cstmt, rs);
		return listaCuentas;
		
	}
    
    public List<ParametroEntity> obtenerTiposDocumento() throws Exception {
    	return comunServiceLocal.obtenerParametrosPorTipo(Constante.TIPO_DOCUMENTOS_ID);
    }

    //@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<Caja> obtenerDatosAperturaCaja(String oficinaId, String terminalId, long tipoId) throws Exception
    {
    	List<Caja> cajas = new ArrayList<Caja>();
    	
    	Connection cnn = null;
    	CallableStatement stm = null;
    	ResultSet rst = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_APERTURA_CARGAR(?,?,?,?,?)}");
			stm.setString(1, oficinaId);
			stm.setString(2, terminalId);
			stm.setLong(3, tipoId);
			stm.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
			stm.registerOutParameter(5, oracle.jdbc.OracleTypes.CURSOR);
			
			stm.execute();
			
			rst = (ResultSet)stm.getObject(4);
			
			//Recorremos las cajas
    		while (rst.next()) {
				Caja caja = new Caja();
				
				caja.setCajaId(rst.getLong("cajaId"));
				caja.setDivisaId(rst.getLong("divisaId"));
				caja.setEstadoId(rst.getLong("estadoId"));
				caja.setMontoDeteriorados(rst.getLong("montoDeteriorados"));
				caja.setPatronCalidad(rst.getLong("patronCalidad"));
				caja.setMontoTotal(rst.getDouble("montoTotal"));
				caja.setMontosDenominacion(new ArrayList<MontoDenominacion>());
				
				cajas.add(caja);
			}
    		
    		rst.close();
			
			rst = (ResultSet)stm.getObject(5);
			
			//Recorremos los montos de las denominaciones
    		while (rst.next()) {
				MontoDenominacion montoDenominacion = new MontoDenominacion();
				
				montoDenominacion.setSecuenciaId(rst.getLong("secuenciaId"));
				montoDenominacion.setCajaId(rst.getLong("cajaId"));
				montoDenominacion.setDivisaId(rst.getLong("divisaId"));
				montoDenominacion.setTipoId(rst.getLong("tipoId"));
				montoDenominacion.setValorTexto(rst.getString("valorTexto"));
				montoDenominacion.setValorNumerico(rst.getString("valorNumerico"));
				montoDenominacion.setValorIngresado(rst.getDouble("valorIngresado"));
				
				for (Caja caja : cajas) {
					if(caja.getDivisaId() == montoDenominacion.getDivisaId()) {
						caja.getMontosDenominacion().add(montoDenominacion);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcHelper.close(cnn,stm,rst);
		}
    	
    	return cajas;
    }

    //@TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void grabarDatosAperturaCaja(Caja caja, String usuario) throws Exception
    {
    	Connection cnn = null;
    	CallableStatement stm = null;
    	
    	try {
    		StringBuffer sb = new StringBuffer(4000);
    		sb.append("<ROOT>");
    		sb.append("<CAJA>");
    		sb.append("<CAJA_ID>"+caja.getCajaId()+"</CAJA_ID>");
    		sb.append("<TIPO_ID>"+caja.getTipoId()+"</TIPO_ID>");
    		sb.append("<DIVISA_ID>"+caja.getDivisaId()+"</DIVISA_ID>");
    		sb.append("<TERMINAL_ID>"+caja.getTerminalId()+"</TERMINAL_ID>");
    		sb.append("<OFICINA_ID>"+caja.getOficinaId()+"</OFICINA_ID>");
    		sb.append("<MONTO_DET>"+caja.getMontoDeteriorados()+"</MONTO_DET>");
    		sb.append("<PATRON_CAL>"+caja.getPatronCalidad()+"</PATRON_CAL>");
    		sb.append("<MONTO_TOT>"+caja.getMontoTotal()+"</MONTO_TOT>");
    		sb.append("<DENOMINACIONES>");
        	for (MontoDenominacion monto : caja.getMontosDenominacion()) {
        		sb.append("<DENOMINACION>");
        		sb.append("<DENOMINACION_ID>"+monto.getDenominacionId()+"</DENOMINACION_ID>");
        		sb.append("<MONTO>"+monto.getValorIngresado()+"</MONTO>");
            	sb.append("</DENOMINACION>");
			}
    		sb.append("</DENOMINACIONES>");
    		sb.append("</CAJA>");
    		sb.append("</ROOT>");
    		
    		System.out.println("XMLTYPE: "+sb.toString());
        	
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_APERTURA_GRABAR(?,?,?,?)}");
			stm.setObject(1, sb.toString());
			stm.setObject(2, usuario);
			stm.setObject(3, new Date(new java.util.Date().getTime()));
			stm.registerOutParameter(4, OracleTypes.VARCHAR);
			
			stm.executeUpdate();
			
			String error = stm.getString(4);
			if(error != null) {
				throw new NegocioException(error);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			JdbcHelper.close(cnn,stm);
		}
    }

    //@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<Caja> obtenerDatosCierreCaja(String oficinaId, String terminalId, long tipoId) throws Exception
    {
    	List<Caja> cajas = new ArrayList<Caja>();
    	
    	Connection cnn = null;
    	CallableStatement stm = null;
    	ResultSet rst = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_CIERRE_CARGAR(?,?,?,?,?)}");
			stm.setString(1, oficinaId);
			stm.setString(2, terminalId);
			stm.setLong(3, tipoId);
			stm.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
			stm.registerOutParameter(5, oracle.jdbc.OracleTypes.CURSOR);
			
			stm.execute();
			
			rst = (ResultSet)stm.getObject(4);
			
			//Recorremos las cajas
    		while (rst.next()) {
				Caja caja = new Caja();
				
				caja.setCajaId(rst.getLong("cajaId"));
				caja.setDivisaId(rst.getLong("divisaId"));
				caja.setEstadoId(rst.getLong("estadoId"));
				caja.setMontoDeteriorados(rst.getLong("montoDeteriorados"));
				caja.setPatronCalidad(rst.getLong("patronCalidad"));
				caja.setMontoTotal(rst.getDouble("montoTotal"));
				caja.setMontosDenominacion(new ArrayList<MontoDenominacion>());
				
				cajas.add(caja);
			}
    		
    		rst.close();
			
			rst = (ResultSet)stm.getObject(5);
			
			//Recorremos los montos de las denominaciones
    		while (rst.next()) {
				MontoDenominacion montoDenominacion = new MontoDenominacion();
				
				montoDenominacion.setSecuenciaId(rst.getLong("secuenciaId"));
				montoDenominacion.setCajaId(rst.getLong("cajaId"));
				montoDenominacion.setDivisaId(rst.getLong("divisaId"));
				montoDenominacion.setTipoId(rst.getLong("tipoId"));
				montoDenominacion.setValorTexto(rst.getString("valorTexto"));
				montoDenominacion.setValorNumerico(rst.getString("valorNumerico"));
				montoDenominacion.setValorIngresado(rst.getDouble("valorIngresado"));
				
				for (Caja caja : cajas) {
					if(caja.getDivisaId() == montoDenominacion.getDivisaId()) {
						caja.getMontosDenominacion().add(montoDenominacion);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcHelper.close(cnn,stm,rst);
		}
    	
    	return cajas;
    }

    //@TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void grabarDatosCierreCaja(Caja caja, String usuario) throws Exception
    {
    	Connection cnn = null;
    	CallableStatement stm = null;
    	
    	try {
    		StringBuffer sb = new StringBuffer(4000);
    		sb.append("<ROOT>");
    		sb.append("<CAJA>");
    		sb.append("<CAJA_ID>"+caja.getCajaId()+"</CAJA_ID>");
    		sb.append("<TIPO_ID>"+caja.getTipoId()+"</TIPO_ID>");
    		sb.append("<DIVISA_ID>"+caja.getDivisaId()+"</DIVISA_ID>");
    		sb.append("<TERMINAL_ID>"+caja.getTerminalId()+"</TERMINAL_ID>");
    		sb.append("<MONTO_DET>"+caja.getMontoDeteriorados()+"</MONTO_DET>");
    		sb.append("<PATRON_CAL>"+caja.getPatronCalidad()+"</PATRON_CAL>");
    		sb.append("<MONTO_TOT>"+caja.getMontoTotal()+"</MONTO_TOT>");
    		sb.append("<DENOMINACIONES>");
        	for (MontoDenominacion monto : caja.getMontosDenominacion()) {
        		sb.append("<DENOMINACION>");
        		sb.append("<DENOMINACION_ID>"+monto.getDenominacionId()+"</DENOMINACION_ID>");
        		sb.append("<MONTO>"+monto.getValorIngresado()+"</MONTO>");
            	sb.append("</DENOMINACION>");
			}
    		sb.append("</DENOMINACIONES>");
    		sb.append("</CAJA>");
    		sb.append("</ROOT>");
    		
    		System.out.println("XMLTYPE: "+sb.toString());
        	
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_CIERRE_GRABAR(?,?,?,?)}");
			stm.setObject(1, sb.toString());
			stm.setObject(2, usuario);
			stm.setObject(3, new Date(new java.util.Date().getTime()));
			stm.registerOutParameter(4, OracleTypes.VARCHAR);
			
			stm.executeUpdate();
			
			String error = stm.getString(4);
			if(error != null) {
				throw new NegocioException(error);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			JdbcHelper.close(cnn,stm);
		}
    }

    //@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public DatosTraspasoCaja obtenerDatosTraspasoCaja(String oficinaId, String terminalId, long tipoId) throws Exception
    {
    	DatosTraspasoCaja datos = new DatosTraspasoCaja();
    	
    	Connection cnn = null;
    	CallableStatement stm = null;
    	ResultSet rst = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_TRASPASO_CARGAR(?,?,?,?,?)}");
			stm.setString(1, oficinaId);
			stm.setString(2, terminalId);
			stm.setLong(3, tipoId);
			stm.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
			stm.registerOutParameter(5, oracle.jdbc.OracleTypes.CURSOR);
			
			stm.execute();
			
			rst = (ResultSet)stm.getObject(4);

	    	List<Caja> cajas = new ArrayList<Caja>();
			
			//Recorremos las cajas
    		while (rst.next()) {
				Caja caja = new Caja();
				
				caja.setCajaId(rst.getLong("cajaId"));
				caja.setDivisaId(rst.getLong("divisaId"));
				caja.setEstadoId(rst.getLong("estadoId"));
				//caja.setMontoDeteriorados(rst.getLong("montoDeteriorados"));
				//caja.setPatronCalidad(rst.getLong("patronCalidad"));
				//caja.setMontoTotal(rst.getDouble("montoTotal"));
				
				cajas.add(caja);
			}
    		
    		datos.setCajas(cajas);
    		
    		rst.close();
			
			rst = (ResultSet)stm.getObject(5);

	    	List<Opcion> remesas = new ArrayList<Opcion>();
			
			//Recorremos las remesas
    		while (rst.next()) {
				Opcion opcion = new Opcion();
				
				opcion.setCodigo(rst.getString("TERMINAL_ID"));
				opcion.setValor(rst.getString("DESCRIPCION"));
				
				remesas.add(opcion);
			}
    		
    		datos.setRemesas(remesas);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcHelper.close(cnn,stm,rst);
		}
    	
    	return datos;
    }
    @Transactional(propagation=Propagation.REQUIRED)
    public void grabarDatosTraspasoCaja(TraspasoCajaEntity traspaso, String usuario) throws Exception
    {
    	Connection cnn = null;
    	CallableStatement stm = null;
    	
    	try {
    		Caja cajaOrigen  = traspaso.getCajaOrigen();
    		Caja cajaDestino = traspaso.getCajaDestino();
    		
    		StringBuffer sb = new StringBuffer(4000);
    		sb.append("<ROOT>");
    		sb.append("<CAJA>");
    		sb.append("<CAJA_ID>"+cajaOrigen.getCajaId()+"</CAJA_ID>");
    		sb.append("<DIVISA_ID>"+cajaOrigen.getDivisaId()+"</DIVISA_ID>");
    		sb.append("<TERMINAL_ID>"+cajaOrigen.getTerminalId()+"</TERMINAL_ID>");
    		sb.append("<MONTO_DET>"+cajaOrigen.getMontoDeteriorados()+"</MONTO_DET>");
    		sb.append("<PATRON_CAL>"+cajaOrigen.getPatronCalidad()+"</PATRON_CAL>");
    		sb.append("<MONTO_TOT>"+cajaOrigen.getMontoTotal()+"</MONTO_TOT>");
    		sb.append("<TERMINAL_TRASPASO_ID>"+cajaDestino.getTerminalId()+"</TERMINAL_TRASPASO_ID>");
    		sb.append("<TIPO_CAJA_TRASPASO_ID>"+cajaDestino.getTipoId()+"</TIPO_CAJA_TRASPASO_ID>");
    		sb.append("<OFICINA_TRASPASO_ID>"+cajaDestino.getOficinaId()+"</OFICINA_TRASPASO_ID>");
    		sb.append("<DENOMINACIONES>");
        	for (MontoDenominacion monto : cajaOrigen.getMontosDenominacion()) {
        		sb.append("<DENOMINACION>");
        		sb.append("<DENOMINACION_ID>"+monto.getDenominacionId()+"</DENOMINACION_ID>");
        		sb.append("<MONTO>"+monto.getValorIngresado()+"</MONTO>");
            	sb.append("</DENOMINACION>");
			}
    		sb.append("</DENOMINACIONES>");
    		sb.append("</CAJA>");
    		sb.append("</ROOT>");
    		
    		System.out.println("XMLTYPE: "+sb.toString());
        	
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_TRASPASO_GRABAR(?,?,?,?)}");
			stm.setObject(1, sb.toString());
			stm.setObject(2, usuario);
			stm.setObject(3, new Date(new java.util.Date().getTime()));
			stm.registerOutParameter(4, OracleTypes.VARCHAR);
			
			stm.executeUpdate();
			
			String error = stm.getString(4);
			if(error != null) {
				throw new NegocioException(error);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			JdbcHelper.close(cnn,stm);
		}
    }
    

    
    
    public CuentaEntityDTO obtenerSaldoCuenta(String cuenta) throws Exception
    {
    	CuentaEntityDTO datos = null;
    	
    	Connection cnn = null;
    	CallableStatement stm = null;
    	ResultSet rst = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_SALDO_OBTENER(?,?)}");
			stm.setString(1, cuenta);
			stm.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
	
			stm.execute();
			
			rst = (ResultSet)stm.getObject(2);
		
			//Recorremos las cajas
    		while (rst.next()) {
				datos = new CuentaEntityDTO();
				datos.setNumerocuenta(rst.getString(3));
				datos.setCodigodivisa(rst.getString(9));
				datos.setSaldodisponible(rst.getDouble(12));
				datos.setSaldocontable(rst.getDouble(13));
			
			}
  
	
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			rst.close();
			JdbcHelper.close(cnn,stm,rst);
		}
    	
    	return datos;
    }
    
    
    

    public void grabarDepositoCheques(OperacionChequeEntity operacion, String usuario) throws Exception
    {
    	Connection cnn = null;
    	CallableStatement stm = null;
    	
    	try {
    		StringBuilder sb = new StringBuilder();
    		sb.append("<ROOT>");
    		sb.append("<OPERACION>");
    		sb.append("<ID>"+operacion.getCodigooperacion()+"</ID>");
    		sb.append("<NUMERO_CUENTA>"+operacion.getNumerocuenta()+"</NUMERO_CUENTA>");
    		sb.append("<ID_DIVISA>"+operacion.getCodigodivisa()+"</ID_DIVISA>");
    		sb.append("<IMPORTE_TOTAL>"+operacion.getImportetotal()+"</IMPORTE_TOTAL>");
    		sb.append("<CHEQUES>");
        	for (ChequeEntity cheque : operacion.getCheques()) {
        		sb.append("<CHEQUE>");
        		sb.append("<ID>"+cheque.getId().getNumerocheque()+"</ID>");
        		sb.append("<TIPO>"+cheque.getTipocheque()+"</TIPO>");
            	sb.append("</CHEQUE>");
			}
    		sb.append("</CHEQUES>");
    		sb.append("</OPERACION>");
    		sb.append("</ROOT>");
    		
    		System.out.println("XMLTYPE: "+sb.toString());
        	
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_GRABAR_CHEQUES(?,?,?)}");
			stm.setObject(1,sb.toString());
			stm.setObject(2,usuario);
			stm.registerOutParameter(3, OracleTypes.VARCHAR);
			
			stm.executeUpdate();
			
			String error = stm.getString(3);
			if(error != null) {
				throw new NegocioException(error);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			JdbcHelper.close(cnn,stm);
		}
    }
    
    public List<TraspasoConfirmacionEntity> obtenerDatosConfirmacionTraspasoCaja(String oficinaId, String terminalId, long tipoId) throws Exception
    {
    	List<TraspasoConfirmacionEntity> confirmaciones = new ArrayList<TraspasoConfirmacionEntity>();
    	
    	Connection cnn = null;
    	CallableStatement stm = null;
    	ResultSet rst = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_CONFIRMACION_CARGAR(?,?,?,?)}");
			stm.setString(1, oficinaId);
			stm.setString(2, terminalId);
			stm.setLong(3, tipoId);
			stm.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
			
			stm.execute();
			
			rst = (ResultSet)stm.getObject(4);
			
			//Recorremos las cajas
    		while (rst.next()) {
    			TraspasoConfirmacionEntity confirmacion = new TraspasoConfirmacionEntity();
				
				confirmacion.setOperacionId(rst.getLong("operacionId"));
				confirmacion.setRegistroId(rst.getString("registroId"));
				confirmacion.setTerminalId(rst.getString("terminalId"));
				confirmacion.setApellidoPaterno(rst.getString("apellidoPaterno"));
				confirmacion.setApellidoMaterno(rst.getString("apellidoMaterno"));
				confirmacion.setNombres(rst.getString("nombres"));
				confirmacion.setOficina(rst.getString("oficina"));
				confirmacion.setDivisa(rst.getString("divisa"));
				confirmacion.setImporte(rst.getBigDecimal("importe"));
				
				confirmaciones.add(confirmacion);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcHelper.close(cnn,stm,rst);
		}
    	
    	return confirmaciones;
    }
    
    public Caja obtenerCajaOperacionPorId(long operacionId) throws Exception {
    	Caja caja = new Caja();
    	
    	Connection cnn = null;
    	CallableStatement stm = null;
    	ResultSet rst = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_OPERACION_CAJA_POR_ID(?,?,?,?,?)}");
			stm.setLong(1, operacionId);
			stm.registerOutParameter(2, oracle.jdbc.OracleTypes.DOUBLE);
			stm.registerOutParameter(3, oracle.jdbc.OracleTypes.DOUBLE);
			stm.registerOutParameter(4, oracle.jdbc.OracleTypes.DOUBLE);
			stm.registerOutParameter(5, oracle.jdbc.OracleTypes.CURSOR);
			
			stm.execute();
			
			caja.setMontoDeteriorados(stm.getDouble(2));
			caja.setPatronCalidad(stm.getDouble(3));
			caja.setMontoTotal(stm.getDouble(4));
			caja.setMontosDenominacion(new ArrayList<MontoDenominacion>());
			
			rst = (ResultSet)stm.getObject(5);			
			
			//Recorremos los montos de las denominaciones
    		while (rst.next()) {
				MontoDenominacion montoDenominacion = new MontoDenominacion();

				montoDenominacion.setTipoId(rst.getLong("tipoId"));
				montoDenominacion.setValorTexto(rst.getString("valorTexto"));
				montoDenominacion.setValorIngresado(rst.getDouble("valorIngresado"));
				
				caja.getMontosDenominacion().add(montoDenominacion);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcHelper.close(cnn,stm,rst);
		}
    	
    	return caja;
    }
    
    public void grabarDatosConfirmacionTraspasoCaja(long operacionId, long estadoId, String usuario) throws Exception
    {
    	Connection cnn = null;
    	CallableStatement stm = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_CONFIRMACION_GRABAR(?,?,?,?)}");
			stm.setObject(1,operacionId);
			stm.setObject(2,estadoId);
			stm.setObject(3,usuario);
			stm.setObject(4,new Date(new java.util.Date().getTime()));
			
			stm.executeUpdate();
    	} catch (Exception e) {
			throw e;
		} finally {
			JdbcHelper.close(cnn,stm);
		}
    }

    //@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public DatosConsultaSaldoFinal obtenerDatosConsultaSaldosFinales(String oficinaId) throws Exception
    {
    	DatosConsultaSaldoFinal datos = new DatosConsultaSaldoFinal();
    	
    	Connection cnn = null;
    	CallableStatement stm = null;
    	ResultSet rst = null;
    	
    	try {
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_SALDOS_FINALES_CARGAR(?,?,?,?,?)}");
			stm.setString(1, oficinaId);
			stm.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
			stm.registerOutParameter(3, oracle.jdbc.OracleTypes.CURSOR);
			stm.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
			stm.registerOutParameter(5, oracle.jdbc.OracleTypes.CURSOR);
			
			stm.execute();
			
			rst = (ResultSet)stm.getObject(2);

			List<Terminal> terminales = new ArrayList<Terminal>();
			
			//Recorremos los Saldos de Terminal
    		while (rst.next()) {
    			Terminal terminal = datos.createTerminal();

    			terminal.setTerminal(rst.getString("TERMINAL_ID"));
    			terminal.setRegistro(rst.getString("REGISTRO_ID"));
				
    			terminales.add(terminal);
			}
    		
    		rst.close();
    		
    		datos.setTerminales(terminales);
			
			rst = (ResultSet)stm.getObject(3);

			List<SaldoTerminal> saldosTerminal = new ArrayList<SaldoTerminal>();
			
			//Recorremos los Saldos de Terminal
    		while (rst.next()) {
    			SaldoTerminal saldoTerminal = datos.createSaldoTerminal();

    			//saldoTerminal.setTipoCajaId(rst.getLong("TIPO_CAJA_ID"));
    			saldoTerminal.setDivisaId(rst.getLong("DIVISA_ID"));
    			saldoTerminal.setTerminal(rst.getString("TERMINAL_ID"));
    			saldoTerminal.setMonto(rst.getBigDecimal("SALDO"));
    			saldoTerminal.setEstado(rst.getString("ESTADO_NOMBRE"));
    			saldoTerminal.setLimite(rst.getString("LIMITE_NOMBRE"));
				
    			saldosTerminal.add(saldoTerminal);
			}
    		
    		rst.close();
    		
	    	datos.setSaldosTerminal(saldosTerminal);
			
			rst = (ResultSet)stm.getObject(4);

	    	List<SaldoDenominacion> saldosDenominacion = new ArrayList<SaldoDenominacion>();

			//Recorremos los Saldos de Denominacion
    		while (rst.next()) {
				SaldoDenominacion saldoDenominacion = datos.createSaldoDenominacion();

				saldoDenominacion.setTipoCajaId(rst.getLong("TIPO_CAJA_ID"));
				saldoDenominacion.setDivisaId(rst.getLong("DIVISA_ID"));
				saldoDenominacion.setTipoDenominacionId(rst.getLong("TIPO_DENOMINACION_ID"));
				saldoDenominacion.setValorTexto(rst.getString("VALOR_TEXTO"));
				saldoDenominacion.setValorIngresado(rst.getBigDecimal("VALOR_INGRESADO"));
				
				saldosDenominacion.add(saldoDenominacion);
			}
    		
    		rst.close();
    		
    		datos.setSaldosDenominacion(saldosDenominacion);
			
			rst = (ResultSet)stm.getObject(5);

	    	List<SaldoTotal> saldosTotal = new ArrayList<SaldoTotal>();
			
			//Recorremos los Saldos Totales
    		while (rst.next()) {
				SaldoTotal saldoTotal = datos.createSaldoTotal();

				saldoTotal.setTipoCajaId(rst.getLong("TIPO_CAJA_ID"));
				saldoTotal.setDivisaId(rst.getLong("DIVISA_ID"));
				saldoTotal.setMontoDeteriorado(rst.getBigDecimal("MONTO_DETERIORADO"));
				saldoTotal.setPatronCalidad(rst.getBigDecimal("PATRON_CALIDAD"));
				saldoTotal.setMontoTotal(rst.getBigDecimal("MONTO_TOTAL"));
				
				saldosTotal.add(saldoTotal);
			}
    		
    		datos.setSaldosDenominacion(saldosDenominacion);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcHelper.close(cnn,stm,rst);
		}
    	
    	return datos;
    }
    
    public void grabarDepositoEfectivo(OperacionEfectivoEntity efectivo) throws Exception{
    	Connection cnn = null;
    	CallableStatement stm = null;
    	try{
    		cnn = getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_OPERATORIA.SP_GRABAR_EFECTIVO(?,?,?)}");
			stm.setObject(1,"");
			stm.setObject(2,"");
			stm.registerOutParameter(3, OracleTypes.VARCHAR);
			
			stm.executeUpdate();
			
			String error = stm.getString(3);
			if(error != null) {
				throw new NegocioException(error);
			}
    		
    	} catch (Exception e) {
			throw e;
		} finally {
			JdbcHelper.close(cnn,stm);
		}
    }
    

    public List<ParametroEntity> obtenerTiposOperacion() throws Exception {
    	return comunServiceLocal.obtenerParametrosPorTipo(Constante.TIPO_OPERACIONES_ID);
    }
    
    public List<ParametroEntity> obtenerTiposDivisas() throws Exception {
    	return comunServiceLocal.obtenerParametrosPorTipo(Constante.TIPO_DIVISAS_ID);
    }
    
    public List<ParametroEntity> obtenerTiposCheques() throws Exception {
    	return comunServiceLocal.obtenerParametrosPorTipo(Constante.TIPO_CHEQUES_ID);
    }
    
}
